package com.autoglm.android.core.accessibility

import android.accessibilityservice.AccessibilityService
import android.graphics.Bitmap
import android.view.accessibility.AccessibilityNodeInfo
import com.autoglm.android.core.models.Rect
import com.autoglm.android.core.models.UIElement
import com.autoglm.android.core.models.UIElementInfo
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import android.util.Log
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.update

/**
 * 屏幕分析结果数据类
 */
data class ScreenAnalysisResult(
    val success: Boolean,
    val errorMessage: String? = null,
    val elements: List<UIElement> = emptyList(),
    val packageName: String? = null,
    val activityName: String? = null,
    val screenshot: Bitmap? = null
) {
    companion object {
        fun success(
            elements: List<UIElement>,
            packageName: String? = null,
            activityName: String? = null,
            screenshot: Bitmap? = null
        ) = ScreenAnalysisResult(
            success = true,
            elements = elements,
            packageName = packageName,
            activityName = activityName,
            screenshot = screenshot
        )
        
        fun failure(message: String) = ScreenAnalysisResult(
            success = false,
            errorMessage = message
        )
    }
}

/**
 * UI元素数据类，表示界面上的可交互元素
 */
data class UIElement(
    val id: String,
    val text: String,
    val contentDescription: String,
    val resourceId: String,
    val className: String,
    val packageName: String,
    val bounds: Rect,
    val isClickable: Boolean,
    val isScrollable: Boolean,
    val isLongClickable: Boolean,
    val isVisibleToUser: Boolean,
    val isEnabled: Boolean,
    val isChecked: Boolean?,
    val isFocused: Boolean?,
    val children: List<UIElement> = emptyList(),
    val parent: UIElement? = null
)

/**
 * 元素查找条件数据类
 */
data class ElementCriteria(
    val text: String? = null,
    val contentDescription: String? = null,
    val resourceId: String? = null,
    val className: String? = null,
    val location: android.graphics.Rect? = null,
    val isClickable: Boolean? = null,
    val isVisibleToUser: Boolean? = true,
    val customMatcher: ((UIElement) -> Boolean)? = null
) {
    /**
     * 检查元素是否匹配条件
     */
    fun matches(element: UIElement): Boolean {
        if (text != null && !element.text.contains(text)) return false
        if (contentDescription != null && !element.contentDescription.contains(contentDescription)) return false
        if (resourceId != null && element.resourceId != resourceId) return false
        if (className != null && element.className != className) return false
        if (location != null) {
            val elementRect = android.graphics.Rect(
                element.bounds.left, 
                element.bounds.top, 
                element.bounds.right, 
                element.bounds.bottom
            )
            if (!android.graphics.Rect.intersects(location, elementRect)) return false
        }
        if (isClickable != null && element.isClickable != isClickable) return false
        if (isVisibleToUser != null && element.isVisibleToUser != isVisibleToUser) return false
        if (customMatcher != null && !customMatcher.invoke(element)) return false
        
        return true
    }
}

/**
 * 屏幕分析器，负责分析当前界面并找到界面元素
 */
class ScreenAnalyzer(
    private val accessibilityService: AccessibilityService,
    private val screenCaptureService: ScreenCaptureService
) {
    companion object {
        private const val TAG = "ScreenAnalyzer"
    }
    
    // 当前活动窗口信息
    private val _activeWindowInfo = MutableStateFlow<NodeInfo?>(null)
    val activeWindowInfo: StateFlow<NodeInfo?> = _activeWindowInfo.asStateFlow()
    
    /**
     * 更新当前节点信息
     */
    fun updateNodeInfo(rootNode: AccessibilityNodeInfo?) {
        rootNode ?: return
        
        try {
            val nodeInfo = parseNodeInfo(rootNode)
            _activeWindowInfo.update { nodeInfo }
        } catch (e: Exception) {
            Log.e(TAG, "Error updating node info", e)
        }
    }
    
    /**
     * 清除当前节点信息
     */
    fun clearNodeInfo() {
        _activeWindowInfo.update { null }
    }
    
    /**
     * 分析当前界面
     * 
     * @return 包含界面元素的界面信息
     */
    fun analyzeCurrentScreen(): ScreenInfo? {
        val rootNode = _activeWindowInfo.value ?: return null
        
        val packageName = rootNode.packageName
        val className = rootNode.className
        val childCount = rootNode.children.size
        
        val elements = findAllElements(rootNode)
        
        return ScreenInfo(
            packageName = packageName ?: "",
            className = className ?: "",
            childCount = childCount,
            elements = elements
        )
    }
    
    /**
     * 通过描述查找元素
     * 
     * @param description 元素描述
     * @return 找到的节点
     */
    fun findElementByDescription(description: String): AccessibilityNodeInfo? {
        val rootNode = _activeWindowInfo.value?.originalNode ?: return null
        
        return findNodeByDescription(rootNode, description)
    }
    
    /**
     * 通过元素查找条件查找元素
     * 
     * @param targetElement 元素描述
     * @return 找到的节点
     */
    fun findElement(targetElement: String): AccessibilityNodeInfo? {
        val rootNode = _activeWindowInfo.value?.originalNode ?: return null
        
        return when {
            // 尝试通过文本查找
            targetElement.startsWith("text:") -> {
                val text = targetElement.substringAfter("text:")
                findNodeByText(rootNode, text)
            }
            // 尝试通过内容描述查找
            targetElement.startsWith("desc:") -> {
                val desc = targetElement.substringAfter("desc:")
                findNodeByContentDescription(rootNode, desc)
            }
            // 尝试通过资源ID查找
            targetElement.startsWith("id:") -> {
                val id = targetElement.substringAfter("id:")
                findNodeByViewId(rootNode, id)
            }
            // 默认尝试各种方式查找
            else -> {
                findNodeByText(rootNode, targetElement)
                    ?: findNodeByContentDescription(rootNode, targetElement)
                    ?: findNodeByViewId(rootNode, targetElement)
                    ?: findNodeByDescription(rootNode, targetElement)
            }
        }
    }
    
    /**
     * 根据条件查找所有匹配的元素
     * 
     * @param criteria 查找条件
     * @return 匹配的元素列表
     */
    fun findElements(criteria: ElementCriteria): List<ElementInfo> {
        val rootNode = _activeWindowInfo.value ?: return emptyList()
        val matchingNodes = mutableListOf<NodeInfo>()
        
        findMatchingNodes(rootNode, criteria, matchingNodes)
        
        return matchingNodes.map { nodeInfo ->
            ElementInfo(
                id = nodeInfo.id ?: "",
                text = nodeInfo.text,
                contentDescription = nodeInfo.contentDescription,
                resourceId = nodeInfo.resourceId,
                className = nodeInfo.className,
                bounds = nodeInfo.bounds,
                isClickable = nodeInfo.isClickable,
                isScrollable = nodeInfo.isScrollable,
                isLongClickable = nodeInfo.isLongClickable
            )
        }
    }
    
    /**
     * 查找所有界面元素
     */
    private fun findAllElements(rootNode: NodeInfo): List<ElementInfo> {
        val elements = mutableListOf<ElementInfo>()
        
        // 添加当前节点如果有意义
        if (isInteractiveElement(rootNode)) {
            elements.add(
                ElementInfo(
                    id = rootNode.id ?: "",
                    text = rootNode.text,
                    contentDescription = rootNode.contentDescription,
                    resourceId = rootNode.resourceId,
                    className = rootNode.className,
                    bounds = rootNode.bounds,
                    isClickable = rootNode.isClickable,
                    isScrollable = rootNode.isScrollable,
                    isLongClickable = rootNode.isLongClickable
                )
            )
        }
        
        // 递归查找子节点
        for (child in rootNode.children) {
            elements.addAll(findAllElements(child))
        }
        
        return elements
    }
    
    /**
     * 查找匹配条件的节点
     */
    private fun findMatchingNodes(
        node: NodeInfo,
        criteria: ElementCriteria,
        results: MutableList<NodeInfo>
    ) {
        // 检查当前节点是否匹配
        if (nodeMatchesCriteria(node, criteria)) {
            results.add(node)
        }
        
        // 递归查找子节点
        for (child in node.children) {
            findMatchingNodes(child, criteria, results)
        }
    }
    
    /**
     * 检查节点是否匹配条件
     */
    private fun nodeMatchesCriteria(node: NodeInfo, criteria: ElementCriteria): Boolean {
        // 检查文本
        if (criteria.text != null && node.text != criteria.text) {
            return false
        }
        
        // 检查内容描述
        if (criteria.contentDescription != null && node.contentDescription != criteria.contentDescription) {
            return false
        }
        
        // 检查资源ID
        if (criteria.resourceId != null && node.resourceId != criteria.resourceId) {
            return false
        }
        
        // 检查类名
        if (criteria.className != null && node.className != criteria.className) {
            return false
        }
        
        return true
    }
    
    /**
     * 判断元素是否可交互
     */
    private fun isInteractiveElement(node: NodeInfo): Boolean {
        return node.isClickable || node.isScrollable || node.isLongClickable ||
                node.text != null || node.contentDescription != null || node.resourceId != null
    }
    
    /**
     * 通过文本查找节点
     */
    private fun findNodeByText(
        rootNode: AccessibilityNodeInfo,
        text: String
    ): AccessibilityNodeInfo? {
        val nodes = rootNode.findAccessibilityNodeInfosByText(text)
        return nodes.firstOrNull()
    }
    
    /**
     * 通过内容描述查找节点
     */
    private fun findNodeByContentDescription(
        rootNode: AccessibilityNodeInfo,
        description: String
    ): AccessibilityNodeInfo? {
        // 遍历节点树查找匹配的内容描述
        if (rootNode.contentDescription?.toString() == description) {
            return rootNode
        }
        
        for (i in 0 until rootNode.childCount) {
            val child = rootNode.getChild(i) ?: continue
            val found = findNodeByContentDescription(child, description)
            if (found != null) {
                return found
            }
            child.recycle()
        }
        
        return null
    }
    
    /**
     * 通过视图ID查找节点
     */
    private fun findNodeByViewId(
        rootNode: AccessibilityNodeInfo,
        viewId: String
    ): AccessibilityNodeInfo? {
        val nodes = rootNode.findAccessibilityNodeInfosByViewId(viewId)
        return nodes.firstOrNull()
    }
    
    /**
     * 通过描述（文本、内容描述或ID）查找节点
     */
    private fun findNodeByDescription(
        rootNode: AccessibilityNodeInfo,
        description: String
    ): AccessibilityNodeInfo? {
        // 先尝试通过文本查找
        val nodesByText = rootNode.findAccessibilityNodeInfosByText(description)
        if (nodesByText.isNotEmpty()) {
            return nodesByText.first()
        }
        
        // 遍历节点树查找匹配的内容描述
        if (rootNode.contentDescription?.toString() == description) {
            return rootNode
        }
        
        // 检查视图ID
        if (rootNode.viewIdResourceName == description) {
            return rootNode
        }
        
        // 递归查找子节点
        for (i in 0 until rootNode.childCount) {
            val child = rootNode.getChild(i) ?: continue
            val found = findNodeByDescription(child, description)
            if (found != null) {
                return found
            }
            child.recycle()
        }
        
        return null
    }
    
    /**
     * 解析节点信息
     */
    private fun parseNodeInfo(node: AccessibilityNodeInfo): NodeInfo {
        val bounds = android.graphics.Rect()
        node.getBoundsInScreen(bounds)
        
        val children = mutableListOf<NodeInfo>()
        for (i in 0 until node.childCount) {
            val child = node.getChild(i) ?: continue
            children.add(parseNodeInfo(child))
        }
        
        return NodeInfo(
            originalNode = node,
            id = node.viewIdResourceName,
            text = node.text?.toString(),
            contentDescription = node.contentDescription?.toString(),
            resourceId = node.viewIdResourceName,
            className = node.className?.toString(),
            packageName = node.packageName?.toString(),
            bounds = bounds,
            isClickable = node.isClickable,
            isScrollable = node.isScrollable,
            isLongClickable = node.isLongClickable,
            children = children
        )
    }
}

/**
 * 节点信息
 */
data class NodeInfo(
    val originalNode: AccessibilityNodeInfo? = null,
    val id: String? = null,
    val text: String? = null,
    val contentDescription: String? = null,
    val resourceId: String? = null,
    val className: String? = null,
    val packageName: String? = null,
    val bounds: android.graphics.Rect? = null,
    val isClickable: Boolean = false,
    val isScrollable: Boolean = false,
    val isLongClickable: Boolean = false,
    val children: List<NodeInfo> = emptyList()
)

/**
 * 元素信息
 */
data class ElementInfo(
    val id: String,
    val text: String? = null,
    val contentDescription: String? = null,
    val resourceId: String? = null,
    val className: String? = null,
    val bounds: android.graphics.Rect? = null,
    val isClickable: Boolean = false,
    val isScrollable: Boolean = false,
    val isLongClickable: Boolean = false
)

/**
 * 界面信息
 */
data class ScreenInfo(
    val packageName: String,
    val className: String,
    val childCount: Int,
    val elements: List<ElementInfo>
)

/**
 * 元素查找条件
 */
data class ElementCriteria(
    val text: String? = null,
    val contentDescription: String? = null,
    val resourceId: String? = null,
    val className: String? = null
)

 